package sdm.sensor.nasdaq.floe;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.Random;

import de.hdtconsulting.yahoo.finance.YHistoric;
import de.hdtconsulting.yahoo.finance.YQuote;
import de.hdtconsulting.yahoo.finance.YSymbol;
import de.hdtconsulting.yahoo.finance.Yapi;
import de.hdtconsulting.yahoo.finance.csv.format.YFormat;
import de.hdtconsulting.yahoo.finance.csv.format.YTag;

import java.io.*;

public class Stock {
	private YSymbol symbol;
	private Yapi yapi;
	private Tick currentTick; // --> has a state
	
	private boolean boolBackup = false;
	private FileWriter backupFile;
	private BufferedWriter backupBuffer;
	
	private Random randomGenerator = new Random();
	private Iterator<YHistoric> history;
	
	public Stock(String stockSymbol, boolean boolBackup) {
		this.symbol = new YSymbol(stockSymbol);
		this.boolBackup = boolBackup;
		
		yapi = new Yapi();
		yapi.addQuote(symbol);
		
		YFormat format = new YFormat();
		format.setStatusOn(YTag.BID);
		format.setStatusOn(YTag.BID_REAL_TIME);
		format.setStatusOn(YTag.NAME);
		yapi.setFormat(format);
		
		yapi.addTag(YTag.ASK_REAL_TIME);
		yapi.addTag(YTag.LAST_TRADE_DATE);
		yapi.addTag(YTag.LAST_TRADE_TIME);		
		
		
		this.currentTick = new Tick(stockSymbol, 0);
		
		
		if (boolBackup) {
			// write all Ticks to file
			DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
	        try {
				backupFile = new FileWriter(
						"data/" +
						stockSymbol + "__" +
						dateFormat.format(new Date()).toString() + ".txt");
				backupBuffer = new BufferedWriter(backupFile);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		Calendar cal = Calendar.getInstance();
		cal.clear();
		cal.set(2011, 0, 1);
		Date startDate = cal.getTime();
		
		cal.add(cal.DAY_OF_MONTH, 40);
		Date endDate = cal.getTime();
		YQuote quote = yapi.getHistoric(symbol, startDate,endDate, Yapi.HIST_DAYLY);
		startDate = endDate;
		history = quote.getHistorics().iterator();
	}

	public void close() {
		try {
			if (backupBuffer != null) {
				backupBuffer.flush();
				backupBuffer.close();
            }
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	public void refreshCurrentTick() {
		try {
			// .refreshDayTrade() and therefore .refresh() is buggy
			yapi.refreshRealTime();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}

		ArrayList<YQuote> quoteList = yapi.getQuotes();
		YQuote quote = quoteList.get(0);

		currentTick
				.setPrice(Double.valueOf(quote.getValue(YTag.BID_REAL_TIME)));

		if (boolBackup)
			backupCurrentTick();
	}
     
     public void refreshHistoricTick() {
	
		if(history.hasNext()) {
			YHistoric historicQuote = history.next();
			currentTick.setPrice(historicQuote.getClose().doubleValue());
			currentTick.setTimeStamp(new Date());
		}
				
		
		if (boolBackup) backupCurrentTick();

	}
	
	public void randomCurrentTick() {
		double oldPrice = currentTick.getPrice();
		
		currentTick.setPrice(oldPrice + randomGenerator.nextGaussian());
		currentTick.setTimeStamp(new Date());
	}
		
	private void backupCurrentTick() {
		try {
			backupBuffer.write(currentTick.toCsv());
			backupBuffer.newLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public Tick getCurrentTick() {
		return currentTick;
	}
	
	public String getSymbol() {
		return symbol.getCode();
	}
	
	public String toString() {
		return currentTick.toString();
	}
	
	
}
